package nl.boektrust.btsoep.server;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;

import nl.boektrust.btsoep.shared.model.PhysicalBookManifestation;

import org.restlet.data.Status;
import org.restlet.resource.Get;  
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;  
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;

public class RestBookResource extends ServerResource {
	private boolean isObjectifyServiceRegistered = false;
	PersistentServiceImpl persistentServiceImpl = new PersistentServiceImpl();


@Get 
public String retrieve() {
	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	Document doc = null;
	try {
		doc = factory.newDocumentBuilder().newDocument();
	} catch (Exception e) {
		System.err.println("Exception");
		e.printStackTrace();

		System.err.println(e.getMessage());
		System.err.println(e.getStackTrace());
		throw(new ResourceException(new Status(501), "RestBookResource failed to allocate a Document resource, critical error."));
	}
	 
	//PrintWriter out = response.getWriter();
	//response.setContentType("text/xml");
	
	String st = (String) getRequest().getAttributes().get("recordReference");
	System.out.println("book rest resource called with recordreference "+st);
	// check for length of ISBN
	if (st.length() != 13) {
		System.out.println("ISBN is not syntactically correct");
		throw(new ResourceException(new Status(400), "ISBN is not syntactically correct"));
	} 
	// check for all digits of ISBN
	for (int i=0; i<st.length(); i++) {
		if (!Character.isDigit(st.charAt(i))) {
			throw(new ResourceException(new Status(400), "ISBN is not syntactically correct"));
		}
	}
	String isbnString = st.substring(0, 12);


	List<PhysicalBookManifestation> books = persistentServiceImpl.getBooksByISBN(isbnString);
	if (books.size() > 0) {
		PhysicalBookManifestation theBook = books.get(0);

		// 	encode the message
		DocumentFragment onixMessage = OnixUtility.getOnixMessage();
		if (onixMessage == null) {
			System.err.println("fragment is null");
			return "fragment is null";
		}
		doc.appendChild(doc.importNode(onixMessage, true));
		if (onixMessage.getOwnerDocument() == null) {
			System.err.println("owner document is null");
			return "owner document is null";
		}
		// add header
		DocumentFragment header = OnixUtility.getOnixMessageHeader();
		doc.getDocumentElement().appendChild(doc.importNode(header, true));
		
		// add product node for first product
		DocumentFragment product = OnixUtility.encodeToOnix(theBook);
		doc.getDocumentElement().appendChild(doc.importNode(product, true));
		if (theBook.getImageReferences() != null) {
			System.err.println("book has "+theBook.getImageReferences().size()+" images");
		} else {
			System.err.println("book has NO images");

		}
		/*
		System.out.println("Built an XML docFragment with "+onixMessage.getChildNodes().getLength()+" nodes");
		System.out.println("Nodes: ");
		for (int i = 0; i<onixMessage.getChildNodes().getLength(); i++) {
			System.out.println("node "+i+": "+onixMessage.getChildNodes().item(i).getNodeName());
			System.out.println("      has : "+onixMessage.getChildNodes().item(i).getChildNodes().getLength()+" children");
		}
		*/

		// transform and output the book
		Transformer transformer;
		try {
			// see: http://comments.gmane.org/gmane.org.google.gwt/45531
			System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
			transformer = TransformerFactory.newInstance().newTransformer();
			//transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			//javax.xml.transform.Source src = new DOMSource(docFragment.getOwnerDocument());
			//if (src == null) out.println("src is null");
			java.io.StringWriter writer = new StringWriter();
			javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(writer);
			DOMSource source = new DOMSource(doc);
			//out.println("Got an XML; root node has  "+doc.getDocumentElement().getChildNodes().getLength()+" nodes");
			//out.println("First node under rootnode: "+doc.getDocumentElement().getChildNodes().item(0).getNodeName());
			transformer.transform(source, result);
			String xmlString = result.getWriter().toString();
			if (xmlString == null) System.out.println("xmlString is null");
			System.err.println("xmlString: " + xmlString);
			return(xmlString);
		} catch (Exception e) {
			System.err.println("Exception thrown: " + e.getMessage());
			System.out.print("Exception thrown: " + e.getMessage());
			e.printStackTrace();
		}

		
	} else {
		throw(new ResourceException(new Status(404), "Book not found."));
	}
	throw(new ResourceException(new Status(501), "RestBookResource finished without any meaningful status, critical error."));

//	return "";
}
}
